package wang.chunfan.mybatis.aspect;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import wang.chunfan.mybatis.annotation.LogOperation;
import wang.chunfan.mybatis.log.LogProducer;
import wang.chunfan.mybatis.pojo.OperationLog;
import wang.chunfan.mybatis.tool.IpUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect
public class OperationLogAspect {

    @Autowired
    LogProducer logProducer;

    @Pointcut("@annotation(wang.chunfan.mybatis.annotation.LogOperation)")
    public void pointCut() {

    }


    @Around("pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        try {
            Object result = point.proceed();
            long time = System.currentTimeMillis() - beginTime;
            // 保存日志
            saveLog(point, time, "成功");
            return result;
        } catch (Exception e) {
            long time = System.currentTimeMillis() - beginTime;
            // 保存日志
            saveLog(point, time, "失败");
            throw e;
        }
    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time, String status) {
        OperationLog operationLog = new OperationLog();
        // import org.aspectj.lang.reflect.MethodSignature;
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // import java.lang.reflect.Method;
        Method method = signature.getMethod();
        LogOperation operation = method.getAnnotation(LogOperation.class);

        // 使用 RequestContextHolder 获取 request, user-agent： 用户访问工具
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        operationLog.setOperation(operation.value());
        operationLog.setRequestMethod(request.getMethod());
        operationLog.setRequestUri(request.getRequestURI());
        operationLog.setRequestTime(time);
        operationLog.setCreateTime(new Date());
        operationLog.setStatus(status);
        operationLog.setIp(IpUtils.getIpAddr(request));
        operationLog.setUserAgent(request.getHeader("User-Agent"));
        // 获取参数
        try {
            operationLog.setRequestParams(JSON.toJSONString(joinPoint.getArgs()[0]));
        } catch (Exception e) {
            e.printStackTrace();
        }

        logProducer.saveLog(operationLog);
    }

}
